package demo8;

/*
请你来实现一个 myAtoi(string s) 函数，使其能将字符串转换成一个 32 位有符号整数（类似 C/C++ 中的 atoi 函数）。

函数 myAtoi(string s) 的算法如下：

读入字符串并丢弃无用的前导空格
检查第一个字符（假设还未到字符末尾）为正还是负号，读取该字符（如果有）。 确定最终结果是负数还是正数。 如果两者都不存在，则假定结果为正。
读入下一个字符，直到到达下一个非数字字符或到达输入的结尾。字符串的其余部分将被忽略。
将前面步骤读入的这些数字转换为整数（即，"123" -> 123， "0032" -> 32）。如果没有读入数字，则整数为 0 。必要时更改符号（从步骤 2 开始）。
如果整数数超过 32 位有符号整数范围 [−231,  231 − 1] ，需要截断这个整数，使其保持在这个范围内。具体来说，小于 −231 的整数应该被固定为 −231 ，大于 231 − 1 的整数应该被固定为 231 − 1 。
返回整数作为最终结果。
注意：

本题中的空白字符只包括空格字符 ' ' 。
除前导空格或数字后的其余字符串外，请勿忽略 任何其他字符。
 */
public class Test {
    public static void main(String[] args) {
        String str = "+";
        System.out.println(myAtoi(str));

    }

    public static int myAtoi(String s) {

        //leetcode上的评论提供的解法
        int len = s.length();
        // str.charAt(i) 方法回去检查下标的合法性，一般先转换成字符数组
        char[] charArray = s.toCharArray();

        // 1、去除前导空格
        int index = 0;
        while (index < len && charArray[index] == ' ') {
            index++;
        }

        // 2、如果已经遍历完成（针对极端用例 "      "）
        if (index == len) {
            return 0;
        }

        // 3、如果出现符号字符，仅第 1 个有效，并记录正负
        int sign = 1;
        char firstChar = charArray[index];
        if (firstChar == '+') {
            index++;
        } else if (firstChar == '-') {
            index++;
            sign = -1;
        }

        // 4、将后续出现的数字字符进行转换
        // 不能使用 long 类型，这是题目说的
        int res = 0;
        while (index < len) {
            char currChar = charArray[index];
            // 4.1 先判断不合法的情况
            if (currChar > '9' || currChar < '0') {
                break;
            }

            // 题目中说：环境只能存储 32 位大小的有符号整数，因此，需要提前判：断乘以 10 以后是否越界
            if (res > Integer.MAX_VALUE / 10 || (res == Integer.MAX_VALUE / 10 && (currChar - '0') > Integer.MAX_VALUE % 10)) {
                return Integer.MAX_VALUE;
            }
            if (res < Integer.MIN_VALUE / 10 || (res == Integer.MIN_VALUE / 10 && (currChar - '0') > -(Integer.MIN_VALUE % 10))) {
                return Integer.MIN_VALUE;
            }

            // 4.2 合法的情况下，才考虑转换，每一步都把符号位乘进去
            res = res * 10 + sign * (currChar - '0');
            index++;
        }
        return res;

    }

//      自己写的解法，效率很低
//    public static int myAtoi(String s) {
//        //int的可表示范围是[-2147483648,2147483647]
//        //将字符串的开头以及结尾的空格去掉
//        s = s.trim();
//        if(s.length() == 0){
//            //字符串必须有长度才能执行后续操作
//            return 0 ;
//        }
//        //定义可变字符串，将要转型的String存进去
//        StringBuffer sb = new StringBuffer();
//        //根据这个数到底是正数还是负数，循环的结果不同
//        //考虑到第一个数字如果是0，后续也是连续的0，那些就不能加入字符串中，所以定义一个flag来判断
//        boolean flag = true;
//        if(s.charAt(0) == '-'){
////            System.out.println("是有符号负数哦");
//            //负数
//            sb.append("-");
//            //不从0开始，是因为负号占了第一位
//            for (int i = 1; i < s.length() && s.charAt(i)>='0' && s.charAt(i)<='9'; i++) {
//                if(flag){
//                    //如果当前读到的是0，则flag继续，如果不是0，则可以设为flase
//                    if(s.charAt(i) != '0'){
//                        flag = false;
//                        sb.append(s.charAt(i));
//                    }
//                }else{
//                    if(sb.length() == 10){
//                        //第十轮可能存在int溢出
//                        if(Integer.MIN_VALUE/10 > Integer.valueOf(sb.toString())){
//                            //在个位之前就溢出
//                            return Integer.MIN_VALUE;
//                        }else if((Integer.MIN_VALUE/10 == Integer.valueOf(sb.toString()))
//                                && Integer.valueOf(s.charAt(i)+"") == 9){
//                            //在个位溢出
//                            return Integer.MIN_VALUE;
//                        }else{
//                            //没溢出
//                            sb.append(s.charAt(i));
//                        }
//                    }else if( i == 11){
//                        //第十一位，一定溢出
//                        return Integer.MIN_VALUE;
//                    }else{
//                        sb.append(s.charAt(i));
//                    }
//                }
//            }
//        }else if(s.charAt(0) == '+'){
////            System.out.println("是有符号正数哦");
//            //正数
//            //不从0开始，是因为正号占了第一位
//            for (int i = 1; i < s.length() && s.charAt(i)>='0' && s.charAt(i)<='9'; i++) {
//                if(flag){
//                    //如果当前读到的是0，则flag继续，如果不是0，则可以设为flase
//                    if(s.charAt(i) != '0'){
//                        flag = false;
//                        sb.append(s.charAt(i));
//                    }
//                }else{
//                    if(sb.length() == 9){
//                        //第十轮可能存在int溢出
//                        if(Integer.MAX_VALUE/10 < Integer.valueOf(sb.toString())){
//                            //在个位之前就溢出
//                            return Integer.MAX_VALUE;
//                        }else if((Integer.MAX_VALUE/10 == Integer.valueOf(sb.toString()))
//                                && Integer.valueOf(s.charAt(i)+"") > 7){
//                            //在个位溢出
//                            return Integer.MAX_VALUE;
//                        }else{
//                            //没溢出
//                            sb.append(s.charAt(i));
//                        }
//                    }else if( i == 11){
//                        //第十一位，一定溢出
//                        return Integer.MAX_VALUE;
//                    }else{
//                        sb.append(s.charAt(i));
//                    }
//                }
//            }
//        }else if(s.charAt(0)>='0' && s.charAt(0)<='9'){
//            //无符号，是正数
////            System.out.println("是无符号正数哦");
//            //正数
//            //不从0开始，是因为正号占了第一位
//            for (int i = 0; i < s.length() && s.charAt(i)>='0' && s.charAt(i)<='9'; i++) {
//                if(flag){
//                    //如果当前读到的是0，则flag继续，如果不是0，则可以设为flase
//                    if(s.charAt(i) != '0'){
//                        flag = false;
//                        sb.append(s.charAt(i));
//                    }
//                }else{
//                    if(sb.length() == 9){
//                        //第十轮可能存在int溢出
//                        if(Integer.MAX_VALUE/10 < Integer.valueOf(sb.toString())){
//                            //在个位之前就溢出
//                            return Integer.MAX_VALUE;
//                        }else if((Integer.MAX_VALUE/10 == Integer.valueOf(sb.toString()))
//                                && Integer.valueOf(s.charAt(i)+"") > 7){
//                            System.out.println("走了2");
//                            //在个位溢出
//                            return Integer.MAX_VALUE;
//                        }else{
//                            //没溢出
//                            sb.append(s.charAt(i));
//                        }
//                    }else if( i == 10){
//                        //第十一位，一定溢出
//                        return Integer.MAX_VALUE;
//                    }else{
//                        sb.append(s.charAt(i));
//                    }
//                }
//            }
//        }
//
//        //只有没超过9位的数，才会走出循环
//        if(sb.length() == 0 || (sb.length() == 1 && sb.charAt(0) == '-')){
//            //剔除掉只读取了符号，但后续没内容的情况
//            return 0;
//        }else{
//            return Integer.valueOf(sb.toString());
//        }
//    }
}
